using System;
using System.Collections.Generic;
using System.Text;

namespace Chili.Opf3
{
	/// <summary>
	/// This interface that is implemented by objects that are partually persisted.
	/// </summary>
	/// <remarks>
	/// <para>
	/// This interface is implemented by classes that are partually persisted. It
	/// allows the persistent to specify if any members are to persist and return for
	/// each member whether to persist. This interface allows to do powerful change tracking
	/// and updating of only changed members if combined with the 
	/// <see cref="IObjectNotification">IObjectNotification</see> interface.
	/// </para>
	/// </remarks>
	/// <example>
	/// The following example shows how to implement the interface and use it in combination 
	/// with the <see cref="IObjectNotification">IObjectNotification</see> interface.
	/// <code lang="CS">
	/// [Persistent("Users")]
	/// public sealed class User : IPartialPersist, IObjectNotification
	/// {
	///     private Dictionary&lt;string, bool&gt; _changes;
	///     private string _name;
	/// 
	///     [Field("Name")]
	///     public string Name
	///     {
	///         get { return _name; }
	///         set 
	///         { 
	///             _name = value;
	/// 
	///             // Signalize that the property has changed.
	///             SignalizeChange("Name");
	///         }
	///     }
	/// 
	///     // ... Other properties of the persistent.
	/// 	
	///     // Signalizes that a property with the given name has been changed.
	///     private void SignalizeChange(string propertyName)
	///     {
	///         // Adds the changed property to the dictionary.
	///         if (_changes != null &amp;&amp; !_changes.ContainsKey(propertyName))
	///             _changes.Add(propertyName, true);
	///     }
	///
	///     #region IObjectNotification Members
	///
	///     void IObjectNotification.OnAfterPopulated(ObjectNotificationEventArgs e)
	///     {
	///         // Initializes the dictionary holding the changes after having
	///         // finished to populate the persistent object.
	///         _changes = new Dictionary&lt;string, bool&gt;();
	///     }
	/// 
	///     // ... Other methods of the interface.
	/// 
	///     #endregion
	///
	///     #region IPartialPersist Members
	///
	///     // Returns whether a member is to persist.
	///     bool IPartialPersist.IsMemberToPersist(string name, PersistentOperations operation)
	///     {
	///         // Return whether the dictionary contains the property.
	///         // Returning true means that the member is to persist. False means it's to skip.
	///         return _changes.ContainsKey(name);
	///     }
	///
	///     // Gets whether the persistent instance has members to persist.
	///     bool IPartialPersist.HasMembersToPersist
	///     {
	///         get { return _changes.Count > 0; }
	///     }
	///
	///     #endregion
	/// }
	/// </code>
	/// </example>
	public interface IPartialPersist
	{
		/// <summary>
		/// Returns whether a member is to persist.
		/// </summary>
		/// <param name="name">The name of the member to persist.</param>
		/// <param name="operation">The current persistent operation.</param>
		/// <returns>True if the member is to persist; false otherwise.</returns>
		bool IsMemberToPersist(string name, PersistentOperations operation);

		/// <summary>
		/// Gets whehter the persistent instance has members to persist.
		/// </summary>
		bool HasMembersToPersist { get; }
	}
}
